package mi.payment.utils.transaction;

import android.text.TextUtils;

import java.util.HashMap;
import java.util.Map;

import mi.payment.utils.iso8583.DecodePackage;
import mi.payment.utils.iso8583.MsgField;
import mi.payment.utils.iso8583.Utils;
import mi.payment.utils.secure.TerminalSecure;
import sunmi.sunmiui.utils.LogUtil;

/**
 * 封装了根据上送的交易报文
 * 检查POSP返回的报文是否正确的逻辑
 * 返回报文有效性判断方法：
 * 1：判断是否有64域，如果有64域，进行mac判断
 * 2：判断消息类型，是否增加10
 * 3: 比较交易处理码，第一字节必须完全一致
 * 4: 比较流水号，必须完全一致
 * 5: 比较终端号，必须完全一致。
 * 6: 比较商户号，必须完全一致。
 * 7: 比较金额，如果不是部分扣款交易，需要完全一致。
 *
 * @author tomcat on 2017/2/6.
 */
class SignMsgChecker implements ReceiveMsgCheck {

    /**
     * @param responseBytes 返回包
     * @return mac失败 B6，其他 12 成功 00
     */
    public String check(byte[] requestBytes, Map<String, MsgField> requestMap, byte[] responseBytes, Map<String, MsgField> responseMap) {
        HashMap<String, MsgField> request = DecodePackage.unAssembly(requestBytes);
        HashMap<String, MsgField> response = DecodePackage.unAssembly(responseBytes);
        if (response == null || responseBytes == null) {
            return "12";
        }

        MsgField reqField;
        MsgField respField;

        // 1：判断是否有64域，如果有64域，进行mac判断
        MsgField f064 = response.get("F064");
        if (f064 != null) {
            String value = f064.getDataStr();
            if (TextUtils.isEmpty(value)) {
                return "B6";
            } else {
                TerminalSecure.GenerateMAC(responseBytes);
                byte[] mac = new byte[8];
                System.arraycopy(responseBytes, responseBytes.length - 8, mac, 0, 8);
                String macStr = Utils.byte2HexStr(mac);
                LogUtil.e("nsz", "local mac:" + macStr + " ---- server mac:" + value);
                if (!macStr.equals(value)) {
                    return "B6";
                }
            }
        }

        // 2：判断消息类型，是否增加10
        byte[] requestTypeBytes = new byte[2];
        System.arraycopy(requestBytes, 13, requestTypeBytes, 0, 2);
        int requestType = Utils.bcdToint(requestTypeBytes) + 10;
        String responseMsgType = response.get("type").getDataStr();
        int responseType = 0;
        try {
            responseType = Integer.valueOf(responseMsgType);
        } catch (Exception e) {
            e.printStackTrace();
        }
        if (responseType != requestType) {
            return "12A";
        }

        // 3: 比较交易处理码，第一字节必须完全一致
        reqField = request.get("F003");
        respField = response.get("F003");
        if (isTransTypeError(reqField, respField)) {
            return "12A";
        }

        // 5: 比较终端号，必须完全一致。
        reqField = request.get("F041");
        respField = response.get("F041");
        if (isError(reqField, respField)) {
            return "12A";
        }

        // 6: 比较商户号，必须完全一致。
        reqField = request.get("F042");
        respField = response.get("F042");
        if (isError(reqField, respField)) {
            return "12A";
        }

        // 7: 比较金额，如果不是部分扣款交易，需要完全一致。
        reqField = request.get("F004");
        respField = response.get("F004");
        if (isAmountError(reqField, respField)) {
            return "64";
        }

        return "00";
    }

    private boolean isEmpty(MsgField field) {
        return (field == null || field.getDataStr() == null);
    }

    private boolean isError(MsgField reqField, MsgField respField) {
        if (isEmpty(respField)) {
            return true;
        }
        return !isEmpty(reqField) && !reqField.getDataStr().equals(respField.getDataStr());
    }

    private boolean isAmountError(MsgField reqField, MsgField respField) {
        return !isEmpty(reqField) && !isEmpty(respField) && !reqField.getDataStr().equals(respField.getDataStr());
    }

    private boolean isTransTypeError(MsgField reqField, MsgField respField) {
        return !isEmpty(reqField) && !isEmpty(respField) && !reqField.getDataStr().substring(0, 2).equals(respField.getDataStr().substring(0, 2));
    }


}
